home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / utils / pcxutils / pcx2fnt.c < prev    next >
C/C++ Source or Header  |  1993-07-14  |  13KB  |  481 lines

  1. /**************************************************************************
  2.  PCX2FNT - by Lee Hamel (Patch), hamell@cx.pdx.edu, *Avalanche* coder
  3.  July 14th, 1993
  4. **************************************************************************/
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <malloc.h>
  9.  
  10. #undef DEBUG1
  11. #undef DEBUG2
  12. #undef DEBUG3
  13. #undef DEBUG4
  14. #undef DEBUG5
  15. #undef DEBUG6
  16. #undef DEBUG7
  17. #undef DEBUG8
  18. #undef DEBUG9
  19.  
  20. typedef struct {
  21.         char    manufacturer;
  22.         char    version;
  23.         char    encoding;
  24.         char    bits_per_pixel;
  25.         int     xmin,ymin;
  26.         int     xmax,ymax;
  27.         int     hres;
  28.         int     vres;
  29.         char    palette[48];
  30.         char    reserved;
  31.         char    colour_planes;
  32.         int     bytes_per_line;
  33.         int     palette_type;
  34.         char    filler[58];
  35.            } PCXHEAD;
  36.  
  37. #define         PCXHEADSIZE     sizeof(PCXHEAD)
  38.  
  39. PCXHEAD header;
  40. unsigned int width, depth, bytes, i, i1, i2, i3, charcount = 0;
  41. unsigned char palette[768];
  42. unsigned char charrows, charsinrow[20], numcolors = 0, startcolor = 0;
  43. unsigned char buffer[256], charorder[256], xysizes[512], showflag;
  44. FILE *infile, *outfile;
  45. unsigned char *tempptr, *charptr, *rowptr, *picture, *fonts[256];
  46. char pcxfile[20],cfgfile[20],fntfile[20],asmfile[20];
  47.  
  48. void Read_PCX_Line(unsigned int vidoffset)
  49. {
  50.   unsigned char c, run;
  51.   unsigned int n = 0;
  52.  
  53.   _asm
  54.   {
  55.     cld
  56.     mov         di,[vidoffset]
  57.   }
  58.  
  59.   do
  60.   {
  61.     c = fgetc(infile) & 0xff;
  62.     if ((c & 0xc0) == 0xc0)             /* if it's a run of bytes field */
  63.     {
  64.       run = c & 0x3f;                   /* and off the high bits */
  65.       c = fgetc(infile);                /* get the run byte */
  66.       n += run;                         /* run the byte */
  67.       buffer[c] = 1;
  68.       for (i2 = 0; i2 < run; i2++)
  69.     *picture++ = c;
  70.  
  71.       if (showflag == 0)
  72.       {
  73.     _asm
  74.     {
  75.         mov     ax,0a000h
  76.         mov     es,ax
  77.         mov     al,[c]
  78.         xor     ch,ch
  79.         mov     cl,[run]
  80.         rep     stosb
  81.     }
  82.       }
  83.     }
  84.     else
  85.     {
  86.       n++;
  87.       buffer[c] = 1;
  88.       *picture++ = c;
  89.  
  90.       if (showflag == 0)
  91.       {
  92.     _asm
  93.     {
  94.         mov     ax,0a000h
  95.         mov     es,ax
  96.         mov     al,[c]
  97.         stosb
  98.     }
  99.       }
  100.     }
  101.   }
  102.   while (n < bytes);
  103. }
  104.  
  105. void Unpack_PCX_File(void)
  106. {
  107.   for (i = 0; i < 768; i++)
  108.     palette[i] = palette[i] >> 2;
  109.  
  110.   if (showflag == 0)
  111.   {
  112.     _asm
  113.     {
  114.         mov     ax,0013h
  115.         int     10h
  116.         mov     ax,1012h
  117.         xor     bx,bx
  118.         mov     cx,256
  119.         mov     dx,offset palette
  120.         int     10h
  121.     }
  122.   }
  123.  
  124.   rowptr = picture = (unsigned char *) malloc((size_t) 64000);
  125.   for (i = 0; i < depth; i++)
  126.     Read_PCX_Line(i * 320);
  127. }
  128.  
  129. void Get_CFG_File(char *cfgfile)
  130. {
  131.   char tempstr[80],temp1[5],temp2[5],num[5];
  132.   FILE *fp;
  133.  
  134.   for (i = 0; i < 512; i++)
  135.     xysizes[i] = 0;
  136.  
  137.   i = 0;
  138.   if ((fp = fopen(cfgfile,"rt")) != NULL)
  139.   {
  140.     do
  141.     {
  142.     fgets(tempstr,80,fp);
  143.     }
  144.     while (tempstr[0] == ';' || tempstr[0] == '\n');
  145.  
  146.     #ifdef DEBUG8
  147.     printf("Tempstr[0] and [1] = [%d] [%d]\n",tempstr[0],tempstr[1]);
  148.     #endif
  149.  
  150.     sscanf(tempstr,"%s = %d",tempptr,& charrows);
  151.     fgets(tempstr,80,fp);
  152.     tempptr = strchr(tempstr,'=');
  153.     tempptr += 2;
  154.  
  155.     #ifdef DEBUG8
  156.     printf("Charrows = [%d]\n",charrows);
  157.     #endif
  158.  
  159.     for (i = 0; i < charrows; i++)
  160.     {
  161.     sscanf(tempptr,"%d",& charsinrow[i]);
  162.  
  163.     #ifdef DEBUG8
  164.         printf("Charsinrow[%d] = [%d]\n",i,charsinrow[i]);
  165.     #endif
  166.  
  167.     while (*tempptr != ' ') tempptr++;
  168.     tempptr++;
  169.     }
  170.  
  171.     i = 0;
  172.     while (fgets(tempstr,80,fp) != NULL)
  173.     {
  174.       if (tempstr[0] != ';' && tempstr[0] != '\n')
  175.       {
  176.     if (sscanf(tempstr,"%s = %s x %s",num,temp1,temp2) != -1)
  177.     {
  178.       #ifdef DEBUG1
  179.         printf("Num = [%s], Temp1 = [%s], Temp2 = [%s]\n",
  180.            num,temp1,temp2);
  181.       #endif
  182.  
  183.       charorder[i++] = atoi(num);
  184.       charcount++;
  185.       xysizes[2*atoi(num) + 0] = atoi(temp1);
  186.       xysizes[2*atoi(num) + 1] = atoi(temp2);
  187.     }
  188.       }
  189.     }
  190.     fclose(fp);
  191.   }
  192.   else
  193.   {
  194.     fcloseall();
  195.     printf("Could not open file %s\n",cfgfile);
  196.     exit(1);
  197.   }
  198.  
  199.   #ifdef DEBUG1
  200.   for (i = 0; i < 256; i++)
  201.     printf("Index[%3d] = x(%d), y(%d)\n",i,xysizes[i*2],xysizes[(i*2)+1]);
  202.   #endif
  203. }
  204.  
  205. void Dump_Fonts(void)
  206. {
  207.   unsigned int ord = 0, xsize, ysize, highesty;
  208.  
  209.   #ifdef DEBUG4
  210.   for (i = 0; i < 256; i++)
  211.   {
  212.     fonts[i] = (char *) malloc((size_t) 2);
  213.     *fonts[i] = i;
  214.     *(fonts[i] + 1) = i + 1;
  215.   }
  216.   for (i = 0; i < 256; i++)
  217.     printf("Fonts[%d] = %d %d\n",i,*fonts[i],*(fonts[i]+1));
  218.   free((char *) fonts);
  219.   return;
  220.   #endif
  221.  
  222.   #ifdef DEBUG5
  223.       for (ord = 0; ord < charcount; ord++)
  224.       printf("char [%c] [%3d] x-size = %2d\ty-size = %2d\n",
  225.          charorder[ord], charorder[ord],
  226.          xysizes[charorder[ord]*2],
  227.          xysizes[(charorder[ord]*2)+1]);
  228.       return;
  229.   #endif
  230.  
  231.   #ifdef DEBUG6
  232.       picture = rowptr + 320;
  233.       for (i = 0; i < xysizes[charorder[ord]*2]; i++)
  234.       printf("Bitmap = %3d\n",*picture++);
  235.       return;
  236.   #endif
  237.  
  238.   for (i = 0; i < charrows; i++)
  239.   {
  240.     /* reset pointer to UL corner of character row */
  241.     /* +320 to skip over blank row */
  242.  
  243.     highesty = 0;                       /* longest font initialize */
  244.     rowptr += 320;
  245.     picture = rowptr;
  246.  
  247.     for (i3 = 0; i3 < charsinrow[i]; i3++)
  248.     {
  249.       /* UL corner of char */
  250.       charptr = picture;
  251.       xsize = xysizes[charorder[ord]*2];
  252.       ysize = xysizes[(charorder[ord]*2)+1];
  253.  
  254.       #ifdef DEBUG9
  255.       printf("Ord   = [%d]     Charorder[ord] = [%d]\n",
  256.          ord,charorder[ord]);
  257.       printf("Xsize = [%d]     Ysize = [%d]\n",xsize,ysize);
  258.       #endif
  259.  
  260.       if (ysize > highesty) highesty = ysize;
  261.  
  262.       tempptr = fonts[charorder[ord]] =
  263.       (unsigned char *) malloc((size_t) xsize * ysize);
  264.  
  265.       for (i1 = 0; i1 < xsize; i1++)    /* X value */
  266.       {
  267.     for (i2 = 0; i2 < ysize; i2++)  /* Y value */
  268.     {
  269.       *tempptr++ = *picture;
  270.       picture += 320;
  271.     }
  272.  
  273.     picture++;                      /* next column over */
  274.     picture -= 320*ysize;           /* back to top of column */
  275.       }
  276.  
  277.       ord++;                            /* next char in order */
  278.       picture = charptr + xsize + 1;    /* jump to next UL corner */
  279.     }
  280.     /* Jump to start of next char row */
  281.     rowptr += (320 * highesty);
  282.  
  283.     #ifdef DEBUG7
  284.     printf("Ord = [%u]     Highesty = [%u]\n",
  285.            ord, highesty);
  286.     #endif
  287.   }
  288.  
  289.   i1 = 1285;
  290.   for (i = 0; i < 256; i++)
  291.   {
  292.     xsize = xysizes[i*2];
  293.     ysize = xysizes[(i*2)+1];
  294.     fwrite(&i1, 2, 1, outfile);
  295.     i1 += (xysizes[i * 2] * xysizes[(i * 2) + 1]) + 3;
  296.   }
  297.  
  298.   for (i = 0; i < 256; i++)
  299.   {
  300.     xsize = xysizes[i*2];
  301.     ysize = xysizes[(i*2)+1];
  302.     if (xsize == 0 && ysize == 0)
  303.       fprintf(outfile,"%c%c%c",i,0,0);
  304.     else
  305.     {
  306.       fprintf(outfile,"%c%c%c",i,xsize,ysize);
  307.       for (i1 = 0, charptr = fonts[i]; i1 < xsize * ysize; i1++)
  308.     fprintf(outfile,"%c",*charptr++);
  309.     }
  310.   }
  311.  
  312.   for (i = 0; i < charcount; i++)
  313.       free((unsigned char *) fonts[i]);
  314. }
  315.  
  316. void Help(char helptype)
  317. {
  318.   printf("\n");
  319.   printf("PCX2FNT - Converts a PCX pic to FNT format\n");
  320.   printf("    by Patch (hamell@rigel.cs.pdx.edu)    \n");
  321.   printf("──────────────────────────────────────────\n");
  322.   if (helptype == 1)
  323.   {
  324.     printf("FNT format\n");
  325.     printf("──────────\n");
  326.     printf("byte 00h - 02h : string signature 'LMH' (for error checking)\n");
  327.     printf("byte 03h       : # of colors used by the fonts\n");
  328.     printf("byte 04h       : starting palette color used by the fonts\n");
  329.     printf("byte 05h - 772 : RGB data for 256 possible colors\n");
  330.     printf("word 773 - 1284: offset of all 256 ASCII chars, relative to byte 0\n");
  331.     printf("byte 1285 -    : data for the fonts\n");
  332.     printf("                 1st byte is the char in the ASCII table\n");
  333.     printf("                 2nd byte is the X size (width)\n");
  334.     printf("                 3rd byte is the Y size (height)\n");
  335.     printf("                 X*Y bytes of the font - saved column by column\n");
  336.     printf("                        top to bottom, left to right\n\n");
  337.     printf("Fonts are expected to be in the following format:\n");
  338.     printf("┌─┬─┬─┬─┬─┬──┬────  Note the 0s along the top row and far right column.\n");
  339.     printf("0 0 0 0 0 0 ─┤      This is an example of the pixel placement of an A.\n");
  340.     printf("0 1 1 1 0 0 ─┤      The 1s represent where the different colors are at.\n");
  341.     printf("1 1 1 1 1 0 ─┤      When drawing the fonts, make sure each lettter has a\n");
  342.     printf("1 1 0 1 1 0 ─┤      border along the top side, otherwise the conversion\n");
  343.     printf("1 1 1 1 1 0 ─┤      algorithm will mess up.  Just stack all of your fonts\n");
  344.     printf("1 1 0 1 1 0 ─┤      on top of each other and side by side, save the picture\n");
  345.     printf("1 1 0 1 1 0 ─┤      as a PCX, and you're done!\n");
  346.   }
  347.   else
  348.   {
  349.     printf("Usage: pcx2fnt [-FNT] PCXFILE [-SHOW]\n");
  350.     printf("where: -FNT       - show the FNT format\n");
  351.     printf("       PCXFILE    - the PCX file to read (no extension)\n");
  352.     printf("       -SHOW      - show the PCX on the screen\n\n");
  353.     printf("Example call: pcx2fnt fontfile -show\n");
  354.     printf("- This will read the file FONTFILE, show it to the screen, and\n");
  355.     printf("  will read the configuration information from FONTFILE.CFG.\n\n");
  356.     printf("Example FONTFILE.CFG:\n");
  357.     printf("charrows = 4\n");
  358.     printf("charsinrow = 3 4 5 6\n");
  359.     printf("065 = 10 x 10\n\n");
  360.     printf("The program expects 4 rows of fonts with 3 fonts in the 1st row, 4 in the 2nd,\n");
  361.     printf("5 in the 3rd, and 6 in the 4th.  065 represents ASCII char A, and it is a\n");
  362.     printf("10 x 10 bitmap.  The file FONTFILE.FNT will be created.  Use a paint\n\n");
  363.     printf("program to figure out the pixel count.  The blank border along the top and right\n");
  364.     printf("of each font DOES NOT count as part of the height or width!\n");
  365.   }
  366.   exit(1);
  367. }
  368.  
  369. void main(int argc, char *argv[])
  370. {
  371.   if (stricmp("-FNT",argv[1]) == 0) Help(1);
  372.   if (argc == 1) Help(0);
  373.  
  374.   {
  375.     strcpy(pcxfile,argv[1]);
  376.     strcpy(cfgfile,argv[1]);
  377.     strcpy(fntfile,argv[1]);
  378.     strcpy(asmfile,argv[1]);
  379.     strcat(pcxfile,".pcx");
  380.     strcat(cfgfile,".cfg");
  381.     strcat(fntfile,".fnt");
  382.     strcat(asmfile,".asm");
  383.  
  384.     if ((infile = fopen(pcxfile,"rb")) != NULL)
  385.     {
  386.       if (fread((char *)&header,1,PCXHEADSIZE,infile) == PCXHEADSIZE)
  387.       {
  388.     if (header.manufacturer == 0x0a && header.version == 5)
  389.     {
  390.       if (!fseek(infile,-769L,SEEK_END))
  391.       {
  392.         if (fgetc(infile) == 0x0c && fread(palette,1,768,infile) == 768)
  393.         {
  394.           fseek(infile,128L,SEEK_SET);
  395.           width = header.xmax - header.xmin + 1;
  396.           depth = header.ymax - header.ymin + 1;
  397.           bytes = header.bytes_per_line;
  398.  
  399.           /*
  400.           printf("Width = %d\n",width);
  401.           printf("Depth = %d\n",depth);
  402.           printf("Bytes = %d\n",bytes);
  403.           printf("Chars per row = %d\n",charsrow);
  404.           */
  405.  
  406.           showflag = stricmp("-SHOW",argv[2]);
  407.           Get_CFG_File(cfgfile);
  408.           Unpack_PCX_File();
  409.  
  410.           #ifdef DEBUG2
  411.           for (i = 0; i < 256; i++)
  412.         printf("Charorder[%3d] = %d\n",i,charorder[i]);
  413.           #endif
  414.  
  415.           #ifdef DEBUG3
  416.           for (i = 0; i < 256; i++)
  417.         printf("Buffer[%3d] = %d\n",i,buffer[i]);
  418.           #endif
  419.  
  420.           outfile = fopen(fntfile,"wb");
  421.  
  422.           for (i = 1; i < 255; i++)         /* ignore use of colors 0 and 255 */
  423.         if (buffer[i] == 1) numcolors++;
  424.  
  425.           for (i = 1; i < 255; i++)         /* ignore use of colors 0 and 255 */
  426.         if (startcolor != 0) break;
  427.           else if (buffer[i] == 1) startcolor = i;
  428.  
  429.           fprintf(outfile,"LMH");
  430.           fprintf(outfile,"%c%c",numcolors,startcolor);
  431.           for (i = 0; i < 256; i++)
  432.           {
  433.         fprintf(outfile,"%c%c%c",palette[(i*3)+0],
  434.                      palette[(i*3)+1],
  435.                      palette[(i*3)+2]);
  436.           }
  437.  
  438.           Dump_Fonts();
  439.           fclose(outfile);
  440.  
  441.           /*
  442.           outfile = fopen(asmfile,"wt");
  443.           fprintf(outfile,"fontpos         ");
  444.           i1 = 5;
  445.           for (i = 0; i < 256; i++)
  446.           {
  447.         // (X value * Y values) + 3 byte ASCII char,
  448.         //   X,Y header for each char
  449.         fprintf(outfile,"dw      %5u        ; ASCII num %3d, char %c\n                ",
  450.             i1,i,(i >= 32 ? i: ' '));
  451.         i1 += (xysizes[i * 2] * xysizes[(i * 2) + 1]) + 3;
  452.           }
  453.           */
  454.  
  455.           fclose(outfile);
  456.  
  457.           if (showflag == 0)
  458.           {
  459.         _asm
  460.         {
  461.             xor     ax,ax
  462.             int     16h
  463.             mov     ax,0003h
  464.             int     10h
  465.         }
  466.           }
  467.           free((unsigned char *) picture);
  468.         }
  469.         else printf("Error reading palette\n");
  470.       }
  471.       else printf("Error seeking to palette\n");
  472.     }
  473.     else printf("Not a 256 color PCX file\n");
  474.       }
  475.       else printf("Error reading %s\n",argv[4]);
  476.       fclose(infile);
  477.     }
  478.     else printf("Error opening %s\n",argv[4]);
  479.   }
  480. }
  481.